package com.cy.dbsys.service.impl;

import com.cy.commom.annotation.RequiredLog;
import com.cy.commom.exception.ServiceException;
import com.cy.commom.pojo.PageObject;
import com.cy.dbsys.dao.SysUserDao;
import com.cy.dbsys.dao.SysUserRoleDao;
import com.cy.dbsys.pojo.SysUser;
import com.cy.dbsys.pojo.SysUserDept;
import com.cy.dbsys.service.SysUserService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;

    /**基于id修改密码*/
    @Override
    public int updatePassword(String sourcePassword, String newPassword, String confirmPassword) {
        //1.参数校验
        if(StringUtils.isEmpty(sourcePassword))
            throw new IllegalArgumentException("原密码不能为空");
        if(StringUtils.isEmpty(newPassword))
            throw new IllegalArgumentException("新密码不能为空");
        if(!newPassword.equals(confirmPassword))
            throw new IllegalArgumentException("两次输入新密码不一致");
        SysUser sysUser=(SysUser) SecurityUtils.getSubject().getPrincipal();
        String sourceSalt=sysUser.getSalt();
        SimpleHash simpleHash=
                new SimpleHash("md5",sourcePassword,sourceSalt,1);
        if(!sysUser.getPassword().equals(simpleHash.toHex()))
            throw  new IllegalArgumentException("原密码不正确");
        //2.对新密码进行加密
        String newSalt=UUID.randomUUID().toString();
        simpleHash=
                new SimpleHash("md5",newPassword,newSalt,1);
        //3.更新新密码
        int rows=sysUserDao.updatePassword(simpleHash.toHex(),newSalt, sysUser.getId());
        return rows;
    }

    /**(修改模块)2、修改信息和用户与角色的关系数据*/
    @RequiredLog(operation = "修改用户信息")
    @Transactional
    @Override
    public int updateObject(SysUser entity, Integer[] roleIds) {
        //1、校验数据
        if(entity==null)
            throw new IllegalArgumentException("保存对象不能为空");
        if(entity.getDeptId()==null)
            throw new IllegalArgumentException("请为用户分配部门");
        if(StringUtils.isEmpty(entity.getUsername()))
            throw new IllegalArgumentException("用户名不能为空");
        if(roleIds==null || roleIds.length==0)
            throw new IllegalArgumentException("至少要为用户分配角色");
        //2、修改自身信息
        int rows = sysUserDao.updateObject(entity);
        //3、删除用户与角色的关系数据
        sysUserRoleDao.deleteObjectsByUserId(entity.getId());
        //4、新增用户与角色的关系数据
        sysUserRoleDao.insertObjects(entity.getId(),roleIds);
        //5、返回结果
        return rows;
    }


    /**(修改模块)1、根据id查询用户相关信息*/
    @RequiresPermissions("sys:role:update")
    @Override
    public Map<String, Object> findObjectById(Integer userId) {
        //1.合法性验证
        if(userId==null||userId<=0)
            throw new IllegalArgumentException("参数数据不合法,userId="+userId);
        //2.业务查询
        //2.1查询用户信息
        SysUserDept user= sysUserDao.findObjectById(userId);
        if(user==null)
            throw new ServiceException("此用户已经不存在");
        //2.2查询用户对应的角色id
        List<Integer> roleIds= sysUserRoleDao.findRoleIdsByUserId(userId);
        //3.数据封装
        Map<String,Object> map=new HashMap<>();
        map.put("user", user);//这里的key不能随意写,要与客户端取值时的key一致
        map.put("roleIds", roleIds);
        return map;
    }
    /**(添加模块)*/
    @RequiredLog(operation = "添加用户信息")
    @RequiresPermissions("sys:user:add")
    @Transactional
    @Override
    public int saveObject(SysUser entity, Integer[] roleIds) {
        //1.参数校验
        if(entity==null)
            throw new IllegalArgumentException("保存对象不能为空");
        if(StringUtils.isEmpty(entity.getUsername()))
            throw new IllegalArgumentException("用户名不能为空");
        if(StringUtils.isEmpty(entity.getPassword()))
            throw new IllegalArgumentException("密码不能为空");
        if(roleIds==null || roleIds.length==0)
            throw new IllegalArgumentException("至少要为用户分配角色");
        //2对密码进行加密
        String password =entity.getPassword();
        String salt = UUID.randomUUID().toString();
        SimpleHash sh = new SimpleHash(
                    "MD5",//algorithmName 算法
                                 password,//原密码
                                 salt, //盐值
                         1);//hashIterations表示加密次数
        entity.setSalt(salt);
        entity.setPassword(sh.toHex());//将加密结果转换为16进制
        //3.保存用户自身信息
        int rows=sysUserDao.insertObject(entity);
        //4.保存用户角色关系数据
        sysUserRoleDao.insertObjects(entity.getId(), roleIds);
        //5.返回结果
        return rows;

    }
    /**禁用启用*/
    @RequiredLog(operation = "禁用启用")
    @RequiresPermissions("sys:user:update")//相当于一个切入点，判断用户是否有注解描述的权限
    @Override
    public int validById(Integer id,Integer valid) {
        //1.合法性验证
        if(id==null||id<=0)
            throw new IllegalArgumentException("参数不合法,id="+id);
        if(valid==null||(valid!=1&&valid!=0))
            throw new IllegalArgumentException("参数不合法,valid="+valid);
        //2.执行禁用或启用操作(admin为后续登陆用户）
        int rows=sysUserDao.validById(id, valid,"admin");
        //3.判定结果,并返回
        if(rows==0)
            throw new IllegalArgumentException("此记录可能已经不存在");
        return rows;
    }

    /**(查询模块)根据id查询信息*/
    @RequiredLog(operation = "分页查询用户信息")
    @Override
    public PageObject<SysUserDept> findPageObjects(String username, Integer pageCurrent) {
        //1.参数校验
        if(pageCurrent==null||pageCurrent<1)
            throw new IllegalArgumentException("页码值不合法");
        //2.分页查询用户信息
        int pageSize=3;
        //执行查询之前基于pageHelper实现分页设置,并启动数据层的拦截机制
        Page<SysUserDept> page=PageHelper.startPage(pageCurrent,pageSize);
        List<SysUserDept> records=sysUserDao.findPageObjects(username);
        //3.封装结果并返回
        return new PageObject<>((int)page.getTotal(), records,page.getPages(),pageSize,pageCurrent);
    }
}
